package com.tianyu.inspection.service;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.tianyu.inspection.common.model.PageModel;
import com.tianyu.inspection.entity.Project;
import com.tianyu.inspection.entity.SysTypeDef;
import com.tianyu.inspection.entity.model.OperateMo;
import com.tianyu.inspection.entity.model.QueryMo;
import com.tianyu.inspection.mapper.ProjectMapper;
import com.tianyu.inspection.mapper.SysTypeDefMapper;
import com.tianyu.inspection.service.api.ISysTypeDefService;
import io.ocs.model.OcsSimpleModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

import static java.util.stream.Collectors.toList;

/**********************************
 * @Author YSW
 * @Description 通用设施类型服务
 * @Date 2021/1/18 - 09:40
 **********************************/

@Service
@Slf4j
public class SysTypeDefServiceImpl implements ISysTypeDefService {

    @Resource
    private SysTypeDefMapper sysTypeDefMapper;

    @Resource
    private ProjectMapper projectMapper;

    @Resource
    private OcsSimpleModel ocsSimpleModel;


    @Override
    public boolean insert(SysTypeDef sysTypeDef) {
        return 1 == sysTypeDefMapper.insert(sysTypeDef);
    }

    @Override
    public boolean updateById(SysTypeDef sysTypeDef) {
        return 1 == sysTypeDefMapper.updateById(sysTypeDef);
    }

    @Override
    public boolean deleteById(Integer sysTypeDefId, Integer projectId) {
        return 1 == sysTypeDefMapper.delete(Wrappers.<SysTypeDef>lambdaQuery()
                .eq(SysTypeDef::getId,sysTypeDefId)
                .eq(SysTypeDef::getProjectId,projectId)
        );
    }

    @Override
    public SysTypeDef selectById(Integer typeId) {
        return sysTypeDefMapper.selectById(typeId);
    }

    /**
     * 根据项目查询图层类型列表
     *
     * @param projectId 项目ID
     * @return
     */
    @Override
    public List<SysTypeDef> getMapLayerTypeList(Integer projectId) {
        Project project = projectMapper.selectById(projectId);
        List<SysTypeDef> returnTypeList = new ArrayList<>();
        if (Objects.nonNull(project) && Objects.nonNull(project.getSysTypeUse()) && project.getSysTypeUse().size() > 0) {
            JSONArray jsonArray = project.getSysTypeUse();
            List<SysTypeDef> typeList = sysTypeDefMapper.selectList(Wrappers.<SysTypeDef>lambdaQuery().in(SysTypeDef::getId, project.getSysTypeUse()));
            typeList.forEach(sysTypeDef -> {
                if (jsonArray.contains(sysTypeDef.getId())) {
                    if (Objects.nonNull(sysTypeDef.getTypeIcon())) {
                        sysTypeDef.setTypeIcon(ocsSimpleModel.getObjectUrl(sysTypeDef.getTypeIcon()));
                    }
                    final JSONObject jsonObject = JSONObject.from(sysTypeDef.getOtherParam());
                    if (jsonObject != null && jsonObject.getString("mapLayerIcon") !=null){
                        sysTypeDef.setOtherParam(jsonObject.fluentPut("mapLayerIcon",ocsSimpleModel.getObjectUrl(jsonObject.getString("mapLayerIcon"))));
                    }
                    returnTypeList.add(sysTypeDef);
                }
            });
        }
        return returnTypeList;
    }

    /**
     * 根据项目查询图层类型树形结构
     *
     * @param projectId 项目ID
     * @return
     */
    @Override
    public List<SysTypeDef> getMapLayerTypeTree(Integer projectId, Integer parentId) {
        Project project = projectMapper.selectById(projectId);
        List<SysTypeDef> returnTypeList = new ArrayList<>();
        if (Objects.nonNull(project) && Objects.nonNull(project.getSysTypeUse()) && project.getSysTypeUse().size() > 0) {
            List<SysTypeDef> typeList = sysTypeDefMapper.selectList(Wrappers.<SysTypeDef>lambdaQuery().in(SysTypeDef::getId, project.getSysTypeUse()));
            typeList.forEach(sysTypeDef -> {
                if (Objects.nonNull(sysTypeDef.getTypeIcon())) {
                    sysTypeDef.setTypeIcon(ocsSimpleModel.getObjectUrl(sysTypeDef.getTypeIcon()));
                }
                final JSONObject jsonObject = JSONObject.from(sysTypeDef.getOtherParam());
                if (jsonObject != null && jsonObject.getString("mapLayerIcon") !=null){
                    sysTypeDef.setOtherParam(jsonObject.fluentPut("mapLayerIcon",ocsSimpleModel.getObjectUrl(jsonObject.getString("mapLayerIcon"))));
                }
                sysTypeDef.setChildren(new ArrayList<>());
                returnTypeList.add(sysTypeDef);
            });
            return buildTree(typeList, parentId == null ? 83 : parentId);
        }
        return returnTypeList;
    }

    public static List<SysTypeDef> buildTree(List<SysTypeDef> all, Integer parentId) {
        if (CollectionUtils.isEmpty(all)) {
            return Lists.newArrayList();
        }
        List<SysTypeDef> parentList = all.stream()
                .filter(e -> parentId == null ? e.getParentTypeId() == null : parentId.equals(e.getParentTypeId()))
                .collect(toList());
        getSubList(parentList, all);
        return parentList;
    }

    private static void getSubList(List<SysTypeDef> parentList, List<SysTypeDef> all) {
        parentList.forEach(e -> {
            List<SysTypeDef> subList = all.stream().filter(o -> e.getId().equals(o.getParentTypeId())).collect(toList());
            e.setChildren(subList);
            if (!CollectionUtils.isEmpty(subList)) {
                getSubList(subList, all);
            }
        });
    }

    /**
     * 根据项目查询图层类型树形结构
     *
     * @param projectId 项目ID
     * @return
     */
    @Override
    public Set<Integer> getMapLayerTypeTreeIds(Integer projectId, Integer parentId) {
        Project project = projectMapper.selectById(projectId);
        Set<Integer> returnTypeList = new HashSet<>();
        if (Objects.nonNull(project) && Objects.nonNull(project.getSysTypeUse()) && project.getSysTypeUse().size() > 0) {
            List<SysTypeDef> typeList = sysTypeDefMapper.selectList(Wrappers.<SysTypeDef>lambdaQuery()
                    .select(SysTypeDef::getId,SysTypeDef::getParentTypeId)
                    .in(SysTypeDef::getId, project.getSysTypeUse()));
            typeList.forEach(sysTypeDef -> sysTypeDef.setChildren(new ArrayList<>()));
            List<SysTypeDef> parentList = typeList.stream()
                    .filter(e -> parentId == null ? e.getParentTypeId() == null : parentId.equals(e.getParentTypeId()))
                    .collect(toList());
            getSubList(parentList, typeList);
            final HashSet<Integer> ids = new HashSet<>();
            ids.add(parentId);
            return getTypeIds(parentList, ids);
        }
        return returnTypeList;
    }

    private static Set<Integer> getTypeIds(List<SysTypeDef> parentList, Set<Integer> ids) {
        if (ids == null) {
            ids = new HashSet<>();
        }
        for (SysTypeDef sysTypeDef : parentList) {
            ids.add(sysTypeDef.getId());
            if (!sysTypeDef.getChildren().isEmpty()) {
                getTypeIds(sysTypeDef.getChildren(), ids);
            }
        }
        return ids;
    }


    /**
     * 分页查询
     *
     * @param queryMo 参数模型
     * @return ModelMap
     */
    @Override
    public IPage<SysTypeDef> searchListPage(QueryMo queryMo) {
        final IPage<SysTypeDef> modelPage = PageModel.getModelPage(queryMo, sysTypeDefMapper);
        modelPage.getRecords().forEach(sysTypeDef -> {
            if (Objects.nonNull(sysTypeDef.getTypeIcon())) {
                sysTypeDef.setTypeIcon(ocsSimpleModel.getObjectUrl(sysTypeDef.getTypeIcon()));
            }
            final JSONObject jsonObject = JSONObject.from(sysTypeDef.getOtherParam());
            if (jsonObject != null && jsonObject.getString("mapLayerIcon") !=null){
                sysTypeDef.setOtherParam(jsonObject.fluentPut("mapLayerIcon",ocsSimpleModel.getObjectUrl(jsonObject.getString("mapLayerIcon"))));
            }
            sysTypeDef.setChildren(new ArrayList<>());
        });
        return modelPage;
    }

    /**
     * 根据项目查询系统类型
     *
     * @param projectId 项目ID
     * @return
     */
    @Override
    public List<SysTypeDef> searchList(Integer projectId) {
        Project project = projectMapper.selectById(projectId);
        List<SysTypeDef> returnTypeList = new ArrayList<>();
        if (Objects.nonNull(project) && Objects.nonNull(project.getSysTypeUse())) {
            List<SysTypeDef> typeList = sysTypeDefMapper.selectList(Wrappers.<SysTypeDef>lambdaQuery().in(SysTypeDef::getId, project.getSysTypeUse()));
            typeList.forEach(sysTypeDef -> {
                if (Objects.nonNull(sysTypeDef.getTypeIcon())) {
                    sysTypeDef.setTypeIcon(ocsSimpleModel.getObjectUrl(sysTypeDef.getTypeIcon()));
                    final JSONObject jsonObject = JSONObject.from(sysTypeDef.getOtherParam());
                    if (jsonObject != null && jsonObject.getString("mapLayerIcon") !=null){
                        sysTypeDef.setOtherParam(jsonObject.fluentPut("mapLayerIcon",ocsSimpleModel.getObjectUrl(jsonObject.getString("mapLayerIcon"))));
                    }
                    sysTypeDef.setChildren(new ArrayList<>());
                }
                returnTypeList.add(sysTypeDef);
            });
        }
        return returnTypeList;
    }

    /**
     * 通过ID等参数查询一条数据
     *
     * @param queryMo 参数集[实体ID 与 项目ID, 数据状态等]
     * @return 单条记录结果
     */
    @Override
    public SysTypeDef selectOne(QueryMo queryMo) {
        if (Objects.nonNull(queryMo.getEqMap().get("id"))) {
            return sysTypeDefMapper.selectOne(new QueryWrapper<SysTypeDef>().allEq(queryMo.getEqMap()));
        }
        return null;
    }

    /**
     * 插入一条数据
     *
     * @param operateMo 实体对象
     * @return 是否操作成功
     */
    @Override
    public boolean insert(OperateMo operateMo) {
        ObjectMapper objectMapper = new ObjectMapper();
        SysTypeDef generalFacilitiesType = objectMapper.convertValue(operateMo.getEntity(), SysTypeDef.class);
        return 1 == sysTypeDefMapper.insert(generalFacilitiesType);
    }

    /**
     * 通过ID删除一条数据
     *
     * @param queryMo 参数集[实体ID 与 项目ID, 数据状态等]
     * @return 是否操作成功
     */
    @Override
    public boolean delete(QueryMo queryMo) {
        if (Objects.nonNull(queryMo.getEqMap().get("id"))) {
            return 1 == sysTypeDefMapper.delete(new QueryWrapper<SysTypeDef>().allEq(queryMo.getEqMap()));
        }
        return false;
    }

    /**
     * 插入一条数据
     *
     * @param operateMo 更新参数集
     * @return ModelMap
     */
    @Override
    public boolean update(OperateMo operateMo) {
        ObjectMapper objectMapper = new ObjectMapper();
        SysTypeDef generalFacilitiesType = objectMapper.convertValue(operateMo.getEntity(), SysTypeDef.class);
        return 1 == sysTypeDefMapper.update(generalFacilitiesType, new QueryWrapper<SysTypeDef>().allEq(operateMo.getEqMap()));
    }

    /**
     * 通过ID逻辑删除一条数据
     *
     * @param queryMo 参数集[实体ID 与 项目ID, 数据状态]
     * @return 是否操作成功
     */
    @Override
    public boolean logicallyDelete(QueryMo queryMo) {
        return 1 == sysTypeDefMapper.update(
                new SysTypeDef().setState(1),
                new QueryWrapper<SysTypeDef>().allEq(queryMo.getEqMap())
        );
    }
}
